package com.example.multidatasource.aspect;


import com.alibaba.fastjson.JSONObject;
import com.example.multidatasource.annotation.Log;
import com.example.multidatasource.controller.ProTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Method;

@Order(2)
@Slf4j
@Aspect
@Component
public class LogAspect {
    public LogAspect() {
        log.info("log日志开始初始化~");
    }

    /**
     * 定义切点：使用到Log自定义注解的地址都进行代理
     */
    @Pointcut("@annotation(com.example.multidatasource.annotation.Log)")
    public void logPointCut(){
    }

    /**
     * 定义环绕通知
     * @return
     */
    @SuppressWarnings("all")
    @Around(value = "logPointCut()")
    public Object aroundAdvice(ProceedingJoinPoint point) throws Exception {
        Object proceed = null;
        Signature signature = point.getSignature();
        if (!(signature instanceof MethodSignature)){
            throw new Exception("该注解只能使用于方法");
        }
        //Method method = point.getTarget().getClass().getMethod(signature.getName(), ((MethodSignature) signature).getParameterTypes());
        Method method = ((MethodSignature) signature).getMethod();
        Log annotation = method.getAnnotation(Log.class);
        ProTypeEnum name = annotation.name();
        String type = annotation.operType();
        Object[] args = point.getArgs();
        System.out.println(String.format("name:%s operType:%s data:%s",name.toString(),type,JSONObject.toJSONString(args)));
        /*HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        JSONObject jsonObject = retrieveBody(request);
        Integer bookId = jsonObject.getInteger("bookId");
        Integer articleId = jsonObject.getInteger("articleId");*/
        try {
            proceed = point.proceed();
        } catch (Throwable throwable){
            log.error(throwable.getMessage(),throwable);
        }
        return proceed;
    }

    public JSONObject retrieveBody(HttpServletRequest request){
        StringBuilder builder = new StringBuilder();
        try(BufferedReader reader = request.getReader()) {
            String buffer = null;
            while ((buffer = reader.readLine()) != null){
                builder.append(buffer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return JSONObject.parseObject(builder.toString());
    }
}
